/***************************************************************************
 *   oboe.math.Frame                                                       *
 *   Copyright (C) 2011 by Felipe Manga                                    *
 *   lufeboma@gmail.com                                                    *
 *                                                                         *
 *   Permission is hereby granted, free of charge, to any person obtaining *
 *   a copy of this software and associated documentation files (the       *
 *   "Software"), to deal in the Software without restriction, including   *
 *   without limitation the rights to use, copy, modify, merge, publish,   *
 *   distribute, sublicense, and/or sell copies of the Software, and to    *
 *   permit persons to whom the Software is furnished to do so, subject to *
 *   the following conditions:                                             *
 *                                                                         *
 *   The above copyright notice and this permission notice shall be        *
 *   included in all copies or substantial portions of the Software.       *
 *                                                                         *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       *
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    *
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR     *
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
 *   OTHER DEALINGS IN THE SOFTWARE.                                       *
 ***************************************************************************/

package oboe.math
{
	import flash.display.Graphics;
	import flash.display.TriangleCulling;
	import flash.utils.Dictionary;
	
	import oboe.core.Oboe;
	import oboe.core.RenderSettings;
	import oboe.math.*;
	import oboe.math.Triangle3D;

	public class Frame
	{
		protected var index:Vector.<int>;
		protected var verts:Vector.<Number>;
		protected var uvs:Vector.<Number>;
		
		private static var frameCount:int = 0;
		
		public static function getFrameCount():int
		{
			return frameCount;
		}
		
		public function Frame( tris:Array, verts:Vector.<Number>, uvs:Vector.<Number> )
		{
			if( !tris ) return;
			var index:Vector.<int> = this.index = new Vector.<int>( tris.length*3, true );
			this.verts = verts;
			this.uvs = uvs;

			tris.sortOn("z", Array.NUMERIC);
//			tris.sort( 
//				function( a:Triangle3D, b:Triangle3D ):Number
//				{
//					return b.z - a.z;
//				}
//			);
			
			var l:int=tris.length;
			var c:int=tris.length*3-1;
			var u:int=0;
			for each(var tri:Triangle3D in tris )// ( var t:int=0; t<l; ++t )
			{
				index[c--] = tri.pointA;
				index[c--] = tri.pointB;
				index[c--] = tri.pointC;
			}
		}
		
//		private function prepareQDMesh( tris:Vector.<Triangle3D> ):void
//		{
//			this.verts = new Vector.<Number>( tris.length*6, true );
//			this.uvs = new Vector.<Number>( tris.length*6, true );
//			this.index = null;
//			
//			var v:int=0;
//			var u:int=0;
//			for( var i:int=0; i<tris.length; i++ )
//			{
//				var t:Triangle3D = tris[i];
//				
//				this.verts[v++] = t.pointAx; this.verts[v++] = t.pointAy;
//				this.verts[v++] = t.pointBx; this.verts[v++] = t.pointBy;
//				this.verts[v++] = t.pointCx; this.verts[v++] = t.pointCy;
//				
//				this.uvs[u++] = t.uvA.x; this.uvs[u++] = t.uvA.y;
//				this.uvs[u++] = t.uvB.x; this.uvs[u++] = t.uvB.y;
//				this.uvs[u++] = t.uvC.x; this.uvs[u++] = t.uvC.y;
//			}
//		}
		
//		private function prepareIndexedMesh( tris:Vector.<Triangle3D> ):void
//		{
//			this.verts = new Vector.<Number>();
//			this.uvs = new Vector.<Number>();
//			this.index = new Vector.<int>();
//			
//			++frameCount;
//			if( Oboe.flags["DEBUG_3D_CACHE"] )
//			{
//				trace( "Creating frame ", frameCount );				
//			}
//			
//			var tmp:Object = {};
//			var pos:int=0;
//			var p:int;
//			var vertex:Number3D;
//			var uv:Number2D;
//			for( var i:int=0; i<tris.length; i++ )
//			{
//				var t:Triangle3D = tris[i];
////				this.addPoint( tmp, t.pointA, t.uvA );
////				this.addPoint( tmp, t.pointB, t.uvB );
////				this.addPoint( tmp, t.pointC, t.uvC );
//
//				var k:String;
//				
//				vertex = t.pointA; uv=t.uvA;
//				k=int(vertex.x*10)+":"+int(vertex.y*10)+":"+uv.x+":"+uv.y;
//				p=tmp[k];
//				if( !p )
//				{
//					this.verts.push( vertex.x, vertex.y );
//					this.uvs.push( uv.x, uv.y );
//					pos++;
//					tmp[k] = pos;
//					p = pos;
//				}
//				this.index.push( p-1 );
//
//				vertex = t.pointB; uv=t.uvB;
//				k=int(vertex.x*10)+":"+int(vertex.y*10)+":"+uv.x+":"+uv.y;
//				p=tmp[k];
//				if( !p )
//				{
//					this.verts.push( vertex.x, vertex.y );
//					this.uvs.push( uv.x, uv.y );
//					pos++;
//					tmp[k] = pos;
//					p = pos;
//				}
//				this.index.push( p-1 );
//				
//				vertex = t.pointC; uv=t.uvC;
//				k=int(vertex.x*10)+":"+int(vertex.y*10)+":"+uv.x+":"+uv.y;
//				p=tmp[k];
//				if( !p )
//				{
//					this.verts.push( vertex.x, vertex.y );
//					this.uvs.push( uv.x, uv.y );
//					pos++;
//					tmp[k] = pos;
//					p = pos;
//				}
//				this.index.push( p-1 );
//			}
//		}
//		
//		private function addPoint( tmp:Object, vertex:Number3D, uv:Number2D ):void
//		{
//			var x:Number = vertex.x;
//			var y:Number = vertex.y;
//			var k:String = x+":"+y+":"+uv.x+":"+uv.y;
//			var pos:int = this.verts.length/2;
//			
//			if( !tmp.hasOwnProperty(k) )
//			{
//				tmp[k] = pos;
//				this.verts.push( x, y );
//				this.uvs.push( uv.x, uv.y );
//			}
//			else
//			{
//				pos = tmp[k]; 
//			}
//			
//			this.index.push( pos );
//		}
//		
		public function draw( s:RenderSettings ):void
		{
			if( s.texture )
			{
				s.target.beginBitmapFill( s.texture );
				s.target.drawTriangles(
					this.verts,
					this.index,
					this.uvs,
					RenderSettings.CULL_NONE // s.culling
				);
				s.target.endFill();
			}
			else
			{
				var alpha:Number = int(((s.color&0xFF000000)>>24)&0xFF)/255;
				if( alpha > 0 )
				{
					if( alpha > 1 ) alpha = 1;
					s.target.beginFill( s.color, alpha );
					s.target.drawTriangles(
						this.verts,
						this.index,
						null,
						RenderSettings.CULL_NONE // s.culling
					);
					s.target.endFill();
				}
			}
		}
	}
}